package org.lmj.chatroom.service;

import com.alibaba.fastjson.JSONObject;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.group.ChannelGroup;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.websocketx.*;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Map;
import java.util.Set;

import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;


//纯文本的textsocket数据帧
//public class TextWebSocketFrameHandler implements ChannelHandler, EventExecutorGroup { 简化开发
//public class TextWebSocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
@Slf4j
public class TextWebSocketFrameHandler extends SimpleChannelInboundHandler<Object> {
    private static final Logger logger = LoggerFactory.getLogger(TextWebSocketFrameHandler.class);

    private WebSocketServerHandshaker handshaker;


    //当客户端发送消息自动执行
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        // protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof FullHttpRequest) {
            // System.out.println("http=========");
            // 处理HTTP请求
            handleHttpRequest(ctx, (FullHttpRequest) msg);
            return;
        }
        if (msg instanceof WebSocketFrame) {
            // System.out.println("websocket=========");
            // 处理WebSocket请求
            handleWebSocketFrame(ctx, (WebSocketFrame) msg);
            // handleWebSocketFrame(ctx,msg);
        }
    }

    /**
     * 处理WebSocket请求
     *
     * @param ctx
     * @param frame
     */
    private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
        //log.info("aaaa");
        if (frame instanceof CloseWebSocketFrame) {
            //退出聊天室的处理逻辑
            handshaker.close(ctx.channel(), (CloseWebSocketFrame) frame.retain());
            ctx.close();
            return;
        }
        // 没有使用WebSocketServerProtocolHandler，所以不会接收到PingWebSocketFrame。
        // if (frame instanceof PingWebSocketFrame) {
        // ctx.writeAndFlush(new PongWebSocketFrame(frame.content().retain()));
        // return;
        // }
        if (!(frame instanceof TextWebSocketFrame)) {
            //目前只接受文本类型消息的聊天
            throw new UnsupportedOperationException(
                    String.format("%s frame types not supported", frame.getClass().getName()));
        }

        String request = ((TextWebSocketFrame) frame).text();
        logger.debug("收到客户端发送的数据：" + request);
        // 回复心跳
        if (request.length() == 0) {
            ctx.writeAndFlush(new TextWebSocketFrame(""));
            return;
        }
        //this.handleMessage(ctx.channel(), request);
        //System.out.println(obj);
        JSONObject requestJson = (JSONObject) JSONObject.parse(request);
        JSONObject respJson = new JSONObject();
        respJson.put("receiverId",requestJson.get("receiverId"));
        respJson.put("icon", requestJson.get("icon"));
        respJson.put("content", requestJson.get("content"));
        respJson.put("name", requestJson.get("name"));
        respJson.put("senderId", requestJson.get("senderId"));
        // 读取信息，并转发
        Channel incoming = ctx.channel();
        ChannelGroup channels = ChannelsHolder.getChannelGroups().get("all");
        /*for (Channel ct : channels) {
            System.out.println(ct.id() + "all id 这是all频道");
        }*/
        String currentChatType= (String) requestJson.get("chatType");
        if (currentChatType.equals("G")){
            //对聊天室的人都遍历一下
            for (Channel ch : channels) {
                // System.out.println(ch.id() + "   :all chaannel id");
                if (ch != incoming) {
                    //被动接收消息的人
                    respJson.put("type", 1);
                    respJson.put("chatType", "G");
                    ch.writeAndFlush(new TextWebSocketFrame(respJson.toString() + "\n"));
                    //ch.writeAndFlush(new TextWebSocketFrame("用户"+incoming.remoteAddress()+"说："+msg.text()+"\n"));
                } else {
                    //发消息的人
                    respJson.put("type", 2);
                    respJson.put("chatType", "G");
                    ch.writeAndFlush(new TextWebSocketFrame(respJson.toString() + "\n"));
                    //ch.writeAndFlush(new TextWebSocketFrame("我说："+msg.text()+"\n"));
                }
            }
        }else {
            String userId= String.valueOf( requestJson.get("receiverId"));

            Channel cl=ChannelsHolder.K_userId_V_Channel.get(userId);
            if(cl==null){
               throw new RuntimeException("error parameter: error userId,"+userId);
            }
            respJson.put("type", 1);
            respJson.put("chatType", "S");
            cl.writeAndFlush(new TextWebSocketFrame(respJson.toString() + "\n"));

            respJson.put("type",2);
            respJson.put("chatType", "S");
            incoming.writeAndFlush(new TextWebSocketFrame(respJson.toString() + "\n"));
        }




    }
    /**
     * 处理HTTP请求
     *
     * @param ctx
     * @param request
     */
    private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest request) {
        // WebSocket访问，处理握手升级。
        if (request.headers().get("Connection").equals("Upgrade")) {
            // Handshake
            WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory("", null, true);
            handshaker = wsFactory.newHandshaker(request);
            if (handshaker == null) {
                // 无法处理的WebSocket版本
                WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
                return;
            }

            // 验证token
            String token = getRequestParameter(request, "token");
            if (token == null) {
                FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.UNAUTHORIZED,
                        Unpooled.copiedBuffer("Token not found in request url", CharsetUtil.UTF_8));
                ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
                logger.error("Token not found in request url");
                return;
            }


            // 向客户端发送WebSocket握手，完成握手。
            final String userId = token;


          //  System.out.println(userId + "====================useriD是");
            ChannelFuture channelFuture = handshaker.handshake(ctx.channel(), request);
            channelFuture.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    if (!future.isSuccess()) {
                        future.channel().close();
                        return;
                    }

                    // 加入到ChannelHolders中
                    //  System.out.println(userId+"    channel:"+future.channel());
                    log.info("{}用户上线了",userId);
                    ChannelsHolder.addChannel(userId, future.channel());
                }
            });
            return;
        }
        // 普通的HTTP访问
        logger.warn("无效的访问: {}", request.uri());
    }

    /*
     */
//，hahandleradd会自动执行，将脸上的记录下来

    //督导数据，都有记账本记录一下
    //


    /**
     * 得到Http请求的Query String
     *
     * @param req
     * @param name
     * @return
     */
    private static String getRequestParameter(FullHttpRequest req, String name) {
        QueryStringDecoder decoder = new QueryStringDecoder(req.uri());
        Map<String, List<String>> parameters = decoder.parameters();
        Set<Map.Entry<String, List<String>>> entrySet = parameters.entrySet();
        for (Map.Entry<String, List<String>> entry : entrySet) {
            if (entry.getKey().equalsIgnoreCase(name)) {
                return entry.getValue().get(0);
            }
        }
        return null;
    }



    //new DefaultChannelGroup(ImmediateEventExecutor.INSTANCE)
    // private static ChannelGroup channels=new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);//保存所有channel
    // private static ChannelGroup channels=new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);//保存所有channel

   /* @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
       // super.channelUnregistered(ctx);
        Channel incoming=ctx.channel();
        for (Channel ch:channels){
            if (ch!=incoming){
                ch.writeAndFlush("再见："+incoming.remoteAddress()+"离开聊天室");
            }
        }

        channels.remove(incoming);
    }*/

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        //  super.channelRegistered(ctx);
//        for(Channel ch:channels){
//            ChannelId id = ch.id();
//            System.out.println("所有频道ID："+id);
//        }
//        // super.handlerAdded(ctx);  //当有客户端连接时  连接上来的客户端的通道
//        Channel incoming=ctx.channel();
//        for (Channel ch:channels){
//            if (ch!=incoming){
//                ch.writeAndFlush("欢迎："+incoming.remoteAddress()+"进入聊天室");
//            }
//        }
        //   System.out.println("有人来了");
        // channels.add(ctx.channel());
    }


}
